package rootpackege.spring.security;


import javax.sql.DataSource;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl;
/**
 * 启用springSecurity——需要在web.xml中添加filter启用该配置
 * @author BriansPC
 *
 */
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  /**
   * 拦截请求相关配置   不同的配置指令之间 需要通过and()方法连接在一起
   */
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
    //启用默认登录页
      .formLogin()
        .loginPage("/page/login")//指定登录页面访问路径
      .and()
      	//退出时  会清除用户的免登录信息
        .logout()
          .logoutSuccessUrl("/page/index")//自定义成功退出之后跳转的页面
      .and()
      //记住我选项配置 html的input复选框的name值必须是"remember-me"
      .rememberMe()
        .tokenRepository(new InMemoryTokenRepositoryImpl())
        //存在本地的登陆信息的cookie的过期时间
        .tokenValiditySeconds(2419200)
        //私钥名称
        .key("spittrKey")
      .and()
      //启用HTTP Basic认证，主要是用在restful方式提供服务时，远程调用者必须传用户名密码过来用于认证
//       .httpBasic()
//         .realmName("Spittr")
//      .and()
      //设置当访问的是满足ANT风格的通配符/pay/**时，自动启用HTTPS访问方式;.requiresInsecure()标识使用http方式
      .requiresChannel().antMatchers("/pay/**").requiresSecure()
      .and()
      //配置请求级别的安全性细节,如果没有认证的话会自动跳转到登录页面
      .authorizeRequests()
        .antMatchers("/").authenticated()
        //如果访问的路径包含后缀 则也需要加上 如 .antMatchers("/page/home.html").authenticated()
        .antMatchers("/page/home").authenticated()//对于/page/home的请求需要认证
        .antMatchers(HttpMethod.POST, "/spittles").authenticated() //对于spittles的post请求必须要认证
        .antMatchers("/admin").access("isAuthenticated() and principal.username = 'admin' ")
        .anyRequest().permitAll(); //其他所有请求都是允许的 不需要认证
  }
  /**
   * 选择查询用户详细信息的服务֤
   * @param auth
   * @throws Exception
   */
  DataSource datasource;
  
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
    //启用内存用户存储
      .inMemoryAuthentication()
    //添加一个用户明为 user  密码为 password 角色为USER的用户,用户角色可以有多个
        .withUser("user1").password("password").roles("USER")
        .and()
        .withUser("user2").password("password").roles("USER");
    /**
     * 基于数据库表认证的时候  需要做下面配置
     */
//    auth.jdbcAuthentication()
//    .dataSource(datasource);
    
    //第九章中还有其他设置方式 以便实现通过不同的数据源获取数据并实现认证和授权
  }

  
}
